#include "CalculateManager.h"

#include <memory>
#include <vector>
#include <iostream>

#include "FIFOQueue.h"

/**
 * @brief CalculateManager 构造函数初始化成员变量
 */
CalculateManager::CalculateManager() :
	m_useBaseData(false), // 默认不使用背景数据
	m_baseData(),         // 背景数据初始化为空
	m_k(1),               // 默认系数 k 为 1
	m_b(1),               // 默认系数 b 为 1
	stop_loop(false)
{

}

CalculateManager::~CalculateManager()
{
	StopVoltageDataThreads();
}

CalculateManager calculateManager;

// 创建 回调数据 队列
std::vector<std::unique_ptr<FIFOQueue<WaveDataWrapper>>> WaveDataWrapperQueue;
// 初始化 回调数据 队列
void CalculateManager::InitializeWaveDataWrapperQueue() {
	for (int i = 0; i < MAX_CHANNEL_NUMBER; ++i) {
		WaveDataWrapperQueue.push_back(std::make_unique<FIFOQueue<WaveDataWrapper>>(WaveDataQueue_capacity));
	}
}

// 创建 电压值 队列
std::vector<std::unique_ptr<FIFOQueue<VoltageDataWrapper>>> VoltageQueue;
// 初始化 电压值 队列
void CalculateManager::InitializeVoltageQueue() {
	for (int i = 0; i < MAX_CHANNEL_NUMBER; ++i) {
		VoltageQueue.push_back(std::make_unique<FIFOQueue<VoltageDataWrapper>>(VoltageQueue_capacity));
	}
}

/**
 * @brief 设置计算系数 k 和 b
 *
 * @param k 系数 k
 * @param b 系数 b
 */
void CalculateManager::SetKAndB(double k, double b)
{
	m_k = k;
	m_b = b;
}

/**
 * @brief 设置是否使用背景数据进行背景消除
 *
 * @param isUse 是否使用背景数据进行背景消除
 */
void CalculateManager::UseEraseBackground(bool isUse)
{
	m_useBaseData = isUse;
}

/**
 * @brief 获取指定通道的电压数据
 *
 *		从指定通道的队列获取原始数据 转换为电压值 压入指定通道的电压数据队列
 *
 * @param chNo 通道编号 从 1 开始
 * @param interval 数据抽取间隔 要 ≥1
 */
void CalculateManager::GetChannelVoltagesOrWithInterval(uint16_t chNo, uint32_t interval)
{
	uint16_t decode = 0;
	int voltageIndex = 0;  // 用于跟踪填充到 voltageList 的索引

	// 检查错误
	if (chNo < 1 || chNo > MAX_CHANNEL_NUMBER || interval <= 0) {
		std::cout << "Channel" << (int)chNo << " 电压处理前检查错误" << std::endl;
		return; // 或者其他适当的错误处理
	}

	// 获取通道索引
	uint16_t channelIndex = chNo - 1;

	// 临时的原始数据 结构体 申请内存
	std::vector<WaveDataWrapper> packages(MAX_CHANNEL_NUMBER);
	packages[channelIndex].WaveData = std::make_unique<char[]>(MAX_POINT_COUNT);
	if (packages[channelIndex].WaveData == nullptr) {
		// 处理内存分配失败的情况
		std::cout << "Channel" << (int)chNo << " 原始数据结构体初始化错误" << std::endl;
		return;
	}

	// 初始化电压数据结构体
	std::vector<std::unique_ptr<VoltageDataWrapper>> VoltageData(MAX_CHANNEL_NUMBER);
	VoltageData[channelIndex] = std::make_unique<VoltageDataWrapper>();
	VoltageData[channelIndex]->Data = std::make_unique<double[]>(MAX_POINT_COUNT / 2);
	if (VoltageData[channelIndex]->Data == nullptr) {
		std::cout << "Channel" << (int)chNo << " 电压数据结构体初始化错误" << std::endl;
		return;
	}

	// 从队列取出原始数据
	auto& WaveDataWrapper_queue = *WaveDataWrapperQueue[channelIndex];
	if (!WaveDataWrapper_queue.isEmpty()) {
		// 提取数据包
		packages[channelIndex] = std::move(*WaveDataWrapper_queue.pop());
	}
	else {
		std::cout << "Channel" << (int)chNo << " 取出原始数据错误" << std::endl;
		return;
	}

	// 计算新的数据长度
	int totalSamples = packages[channelIndex].WaveDataSize / 2;

	// 遍历数据并解码为电压值，仅计算需要的点
	for (int i = 0; i < totalSamples; i += interval)  // 步长为 interval，跳过不要的点
	{
		decode = (static_cast<uint16_t>((packages[channelIndex].WaveData[2 * i])) << 8) | static_cast<uint8_t>(packages[channelIndex].WaveData[2 * i + 1]);
		// 计算电压值，考虑背景数据、增益和范围
		VoltageData[channelIndex]->Data[voltageIndex] = ((decode - (m_useBaseData ? m_baseData[channelIndex] : 0x8000)) * packages[channelIndex].ADCPreGain * packages[channelIndex].ADCRange / 65536.0) * m_k + m_b;
		voltageIndex++;
	}

	// 计算经过间隔后的数据点数
	VoltageData[channelIndex]->DataSize = totalSamples / interval;

	// 将电压数据压入队列
	auto& voltage_queue = *VoltageQueue[channelIndex];
	if (!voltage_queue.isFull()) {
		// 压入数据包
		//voltage_queue.push(VoltageData[channelIndex]);
		voltage_queue.push(std::move(VoltageData[channelIndex]));
		std::cout << "Channel" << (int)chNo << " voltage 数据计算完成" << std::endl;
	}
	else {
		std::cout << "Channel" << (int)chNo << " 电压数据压入队列错误" << std::endl;
	}
}

// 启动所有线程
void CalculateManager::StartVoltageDataThreads() {
	for (int chNo = 1; chNo <= MAX_CHANNEL_NUMBER; ++chNo) {
		VoltageData_threads.push_back(std::thread(&CalculateManager::VoltageDataTask, this, chNo));
	}
}

// 停止所有线程
void CalculateManager::StopVoltageDataThreads() {
	stop_loop.store(true);  // 设置 stop_loop 为 true，线程退出条件
	for (auto& t : VoltageData_threads) {
		if (t.joinable()) {
			t.join();  // 等待所有线程完成
		}
	}
}

// 每个线程的任务
void CalculateManager::VoltageDataTask(int chNo) {
	while (!stop_loop.load()) {  // 使用 stop_loop 来控制线程的停止
		auto& waveData_queue = *WaveDataWrapperQueue[chNo - 1];  // 获取当前通道的 WaveDataQueue
		if (!waveData_queue.isEmpty()) {
			// 如果队列不是空的，可以进行数据处理
			GetChannelVoltagesOrWithInterval(chNo, 1);
		}

		// 控制线程执行间隔
		std::this_thread::sleep_for(std::chrono::milliseconds(100));  // 每 100ms 执行一次
	}
}


